﻿using System;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using CuteAnt;
using CuteAnt.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
using SSCX509 = System.Security.Cryptography.X509Certificates;

namespace SelfCert
{
	public partial class FrmMain : Form
	{
		#region ** enum GenerateCertificateType **

		private enum GenerateCertificateType
		{
			SelfSigned,
			Root,
			Intermediate,
			EndEntity
		}

		#endregion

		#region @@ Fields @@

		private readonly static AuthorityKeyIdentifierStructure _AuthorityKeyIdentifier;

		private GenerateCertificateType m_certType = GenerateCertificateType.SelfSigned;

		private MemoryStream m_currentCertStream = null;
		private AsymmetricCipherKeyPair m_currentKeyPair = null;

		private X509Certificate m_issuerCert = null;
		private AsymmetricCipherKeyPair m_issuerKeyPair = null;

		#endregion

		#region @@ Constructors @@

		static FrmMain()
		{
			var rsaPubMod = new BigInteger(Convert.FromBase64String("AIhKhUNt2vYrb1O363jQTUg3khlD6jDfPe8pDkmqDZ0hAyDjaCekt2icqEtW/H2BG2BpIIIaaPb8UtdlYToSwsWKjDC2CrlPgKcvddGP40WC12T7arqvyyxxzk56OXi94O+Y3IHr7jgrt5vfWhJncqfC1h2yXHG+e02MuUhImBk4XpN/F1ntaX7+K5FhmqVCrfPhym6Yafni5kiaJCeoQFI9EX1csyx8Hu86tHeGQMKWJee/2EH7DLg4x9l709OowcrGBwuDD1mqq7lRx+jyCyd+Al7o/dknCokkJMyjU8H5210tE//MlhQxngHSL1n0fkAllsHcLFmTwdf83mGuBN8="));
			var rsaPubExp = new BigInteger(Convert.FromBase64String("AQAB"));
			var rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp);
			_AuthorityKeyIdentifier = new AuthorityKeyIdentifierStructure(rsaPublic);
		}

		public FrmMain()
		{
			InitializeComponent();
		}

		#endregion

		#region -- Form Event Handlers --

		private void MainForm_Load(object sender, EventArgs e)
		{
			LoadStoreDropdownLists();
			LoadDefaultSettings();
			cboCertType.SelectedIndex = 0;
		}

		private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
		{
		}

		#endregion

		#region ** CreateCertificate **

		/// <summary>Creates X509 v3 certificate in PKCS12 file format.</summary>
		private void CreateCertificate()
		{
			var cn1 = txtCommonName1.Text;
			if (cn1.IsNullOrWhiteSpace()) { cn1 = "CuteAnt"; }
			var cn2 = txtCommonName2.Text;
			var password = txtPassword.Text;
			if (cn2.IsNullOrWhiteSpace()) { cn2 = "CuteAnt"; }

			try
			{
				var kpgen = new RsaKeyPairGenerator();
				kpgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), cboKeySize.Text.ToInt()));
				m_currentKeyPair = kpgen.GenerateKeyPair();

				var value = String.Empty;

				IDictionary attrs1 = new Hashtable();
				IList ord1 = new ArrayList();
				#region Issuer distinct name

				attrs1[X509Name.CN] = cn1;
				ord1.Add(X509Name.CN);
				value = txtOrganization1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.O] = value; ord1.Add(X509Name.O); }
				value = txtUnitName1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.OU] = value; ord1.Add(X509Name.OU); }
				value = txtEmail1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.E] = value; ord1.Add(X509Name.E); }
				value = txtTelephone1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.TelephoneNumber] = value; ord1.Add(X509Name.TelephoneNumber); }
				value = txtStreet1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.Street] = value; ord1.Add(X509Name.Street); }
				value = txtLocality1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.L] = value; ord1.Add(X509Name.L); }
				value = txtProvince1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.ST] = value; ord1.Add(X509Name.ST); }
				value = txtCountry1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.C] = value; ord1.Add(X509Name.C); }
				value = txtPostalCode1.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs1[X509Name.PostalCode] = value; ord1.Add(X509Name.PostalCode); }

				#endregion

				IDictionary attrs2 = new Hashtable();
				IList ord2 = new ArrayList();
				#region Subject distinct name

				attrs2[X509Name.CN] = cn2;
				ord2.Add(X509Name.CN);
				value = txtOrganization2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.O] = value; ord2.Add(X509Name.O); }
				value = txtUnitName2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.OU] = value; ord2.Add(X509Name.OU); }
				value = txtEmail2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.E] = value; ord2.Add(X509Name.E); }
				value = txtTelephone2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.TelephoneNumber] = value; ord2.Add(X509Name.TelephoneNumber); }
				value = txtStreet2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.Street] = value; ord2.Add(X509Name.Street); }
				value = txtLocality2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.L] = value; ord2.Add(X509Name.L); }
				value = txtProvince2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.ST] = value; ord2.Add(X509Name.ST); }
				value = txtCountry2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.C] = value; ord2.Add(X509Name.C); }
				value = txtPostalCode2.Text;
				if (!value.IsNullOrWhiteSpace()) { attrs2[X509Name.PostalCode] = value; ord2.Add(X509Name.PostalCode); }

				#endregion

				var certGen = new X509V3CertificateGenerator();

				var serial = BigInteger.ProbablePrime(120, new Random());
				certGen.SetSerialNumber(serial);

				if (m_certType == GenerateCertificateType.Intermediate || m_certType == GenerateCertificateType.EndEntity)
				{
					certGen.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(m_issuerCert));
				}
				else
				{
					certGen.SetIssuerDN(new X509Name(ord1, attrs1));
				}
				certGen.SetSubjectDN(new X509Name(ord2, attrs2));
				certGen.SetNotBefore(dtpValidFrom.Value);
				certGen.SetNotAfter(dtpValidTo.Value);
				certGen.SetSignatureAlgorithm(cboSignatureAlgorithm.Text);
				certGen.SetPublicKey(m_currentKeyPair.Public);

				/*
				gen.AddExtension( 
						X509Extensions.AuthorityKeyIdentifier.Id, 
						false, 
						new AuthorityKeyIdentifier( 
								SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public), 
								new GeneralNames(new GeneralName(certName)), 
						serial 
				));*/
				//var policies = new Asn1EncodableVector();
				//policies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
				//var policyMap = new Hashtable();
				//policyMap["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";

				switch (m_certType)
				{
					case GenerateCertificateType.Root:
						certGen.AddExtension(X509Extensions.KeyUsage,
																true,
																new KeyUsage(
																		KeyUsage.DigitalSignature |
																		KeyUsage.KeyCertSign |
																		KeyUsage.CrlSign)
																);
						certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
						//certGen.AddExtension(X509Extensions.CertificatePolicies, true, new DerSequence(policies));
						//certGen.AddExtension(X509Extensions.PolicyMappings, true, new PolicyMappings(policyMap));
						break;
					case GenerateCertificateType.Intermediate:
						certGen.AddExtension(X509Extensions.KeyUsage,
																true,
																new KeyUsage(
																		KeyUsage.DigitalSignature |
																		KeyUsage.KeyCertSign |
																		KeyUsage.CrlSign)
																);
						certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0));
						break;
					case GenerateCertificateType.EndEntity:
						certGen.AddExtension(X509Extensions.KeyUsage,
																true,
																new KeyUsage(
																		KeyUsage.DigitalSignature |
																		KeyUsage.DataEncipherment |
																		KeyUsage.KeyAgreement |
																		KeyUsage.KeyEncipherment |
																		KeyUsage.NonRepudiation)
																);
						certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));
						break;
					case GenerateCertificateType.SelfSigned:
					default:
						certGen.AddExtension(X509Extensions.KeyUsage,
																true,
																new KeyUsage(
																		KeyUsage.DigitalSignature |
																		KeyUsage.DataEncipherment |
																		KeyUsage.KeyAgreement |
																		KeyUsage.KeyEncipherment |
																		KeyUsage.NonRepudiation)
																);
						certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
						break;
				}
				certGen.AddExtension(X509Extensions.ExtendedKeyUsage,
														false,
														new ExtendedKeyUsage(
																KeyPurposeID.IdKPServerAuth,
																KeyPurposeID.IdKPClientAuth,
																KeyPurposeID.IdKPCodeSigning,
																KeyPurposeID.IdKPEmailProtection,
																KeyPurposeID.IdKPIpsecEndSystem,
																KeyPurposeID.IdKPIpsecTunnel,
																KeyPurposeID.IdKPIpsecUser,
																KeyPurposeID.IdKPTimeStamping,
																KeyPurposeID.IdKPOcspSigning,
																KeyPurposeID.IdKPSmartCardLogon,
																KeyPurposeID.AnyExtendedKeyUsage)
														);
				certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(m_currentKeyPair.Public));
				certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier,
														false,
														m_certType == GenerateCertificateType.Intermediate || m_certType == GenerateCertificateType.EndEntity ?
																					new AuthorityKeyIdentifierStructure(m_issuerCert) : _AuthorityKeyIdentifier);

				var cert = certGen.Generate(m_certType == GenerateCertificateType.Intermediate || m_certType == GenerateCertificateType.EndEntity ?
																		m_issuerKeyPair.Private : m_currentKeyPair.Private);

				//cert.CheckValidity();
				cert.CheckValidity(DateTime.UtcNow);

				if (m_certType == GenerateCertificateType.SelfSigned || m_certType == GenerateCertificateType.Root)
				{
					// check verifies in general
					cert.Verify(m_currentKeyPair.Public);

					// check verifies with contained key
					cert.Verify(cert.GetPublicKey());
				}
				else
				{
					// check verifies in general
					cert.Verify(m_issuerKeyPair.Public);
				}

				if (m_currentCertStream != null) { m_currentCertStream.Close(); m_currentCertStream = null; }
				m_currentCertStream = new MemoryStream();
				//if (password.IsNullOrWhiteSpace())
				//{
				//	m_currentCertStream.Write(cert.GetEncoded());
				//}
				//else
				//{
				var certEntry = new X509CertificateEntry(cert);
				//var newStore = new Pkcs12Store();
				var newStore = new Pkcs12StoreBuilder().Build();
				newStore.SetCertificateEntry(cn2, certEntry);
				newStore.SetKeyEntry(cn2, new AsymmetricKeyEntry(m_currentKeyPair.Private), new[] { new X509CertificateEntry(cert) });
				newStore.Save(m_currentCertStream, password.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));
				//}
				m_currentCertStream.Position = 0;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		#endregion

		#region ** SaveAsPFX **

		private void SaveAsPFX()
		{
			var path = txtPath.Text;
			if (path.IsNullOrWhiteSpace()) { path = @"c:\"; }
			var fileName = txtFilename.Text.Trim();

			using (var fs = new FileStream(PathHelper.PathCombineFix(path, fileName + ".pfx"), FileMode.Create, FileAccess.Write))
			{
				m_currentCertStream.Position = 0;
				m_currentCertStream.CopyTo(fs);
			}
		}

		#endregion

		#region ** SaveAsCER **

		private void SaveAsCER()
		{
			var path = txtPath.Text;
			if (path.IsNullOrWhiteSpace()) { path = @"c:\"; }
			var fileName = txtFilename.Text.Trim();
			var pwd = txtPassword.Text.Trim();

			using (var fs = new FileStream(PathHelper.PathCombineFix(path, fileName + ".cer"), FileMode.Create, FileAccess.Write))
			{
				m_currentCertStream.Position = 0;
				SSCX509.X509Certificate2 cert = null;
				if (pwd.IsNullOrWhiteSpace())
				{
					cert = new SSCX509.X509Certificate2(m_currentCertStream.ToArray());
				}
				else
				{
					cert = new SSCX509.X509Certificate2(m_currentCertStream.ToArray(), pwd);
				}
				var buffer = cert.Export(SSCX509.X509ContentType.Cert);
				fs.Write(buffer);
			}
		}

		#endregion

		#region ** SaveCertPublic **

		private void SaveCertPublic()
		{
			var path = txtPath.Text;
			if (path.IsNullOrWhiteSpace()) { path = @"c:\"; }
			var fileName = txtFilename.Text.Trim();

			var rasPublic = m_currentKeyPair.Public as RsaKeyParameters;
			var modulus = rasPublic.Modulus.ToByteArray();
			var exponent = rasPublic.Exponent.ToByteArray();
			using (var write = new StreamWriter(PathHelper.PathCombineFix(path, fileName + ".public")))
			{
				write.WriteLine(Convert.ToBase64String(modulus));
				write.WriteLine(Convert.ToBase64String(exponent));
			}
		}

		#endregion

		#region ** SaveCertPrivte **

		private void SaveCertPrivte()
		{
			var path = txtPath.Text;
			if (path.IsNullOrWhiteSpace()) { path = @"c:\"; }
			var fileName = txtFilename.Text.Trim();

			var rasPrivateParameters = m_currentKeyPair.Private as RsaPrivateCrtKeyParameters;
			var rsaPrivMod = rasPrivateParameters.Modulus.ToByteArray();
			var rsaPrivDP = rasPrivateParameters.DP.ToByteArray();
			var rsaPrivDQ = rasPrivateParameters.DQ.ToByteArray();
			var rsaPrivExp = rasPrivateParameters.Exponent.ToByteArray();
			var rsaPrivP = rasPrivateParameters.P.ToByteArray();
			var rsaPrivQ = rasPrivateParameters.Q.ToByteArray();
			var rsaPrivQinv = rasPrivateParameters.QInv.ToByteArray();
			using (var write = new StreamWriter(PathHelper.PathCombineFix(path, fileName + ".private")))
			{
				write.WriteLine(Convert.ToBase64String(rsaPrivMod));
				write.WriteLine(Convert.ToBase64String(rsaPrivDP));
				write.WriteLine(Convert.ToBase64String(rsaPrivDQ));
				write.WriteLine(Convert.ToBase64String(rsaPrivExp));
				write.WriteLine(Convert.ToBase64String(rsaPrivP));
				write.WriteLine(Convert.ToBase64String(rsaPrivQ));
				write.WriteLine(Convert.ToBase64String(rsaPrivQinv));
			}
		}

		#endregion

		#region ** SaveCertInfo **

		private void SaveCertInfo()
		{
			var path = txtPath.Text;
			if (path.IsNullOrWhiteSpace()) { path = @"c:\"; }
			var fileName = txtFilename.Text.Trim();
			var pwd = txtPassword.Text.Trim();

			using (var write = new StreamWriter(PathHelper.PathCombineFix(path, fileName + ".info")))
			{
				m_currentCertStream.Position = 0;
				SSCX509.X509Certificate2 cert = null;
				if (pwd.IsNullOrWhiteSpace())
				{
					cert = new SSCX509.X509Certificate2(m_currentCertStream.ToArray());
				}
				else
				{
					cert = new SSCX509.X509Certificate2(m_currentCertStream.ToArray(), pwd);
				}
				write.WriteLine("SerialNumber:{0}", cert.SerialNumber);
				write.WriteLine("Thumbprint:{0}", cert.Thumbprint);
				write.WriteLine("PublicKey:{0}", cert.PublicKey.Key.ToXmlString(false));
			}
		}

		#endregion

		#region ** Reset **

		private void Reset()
		{
			if (m_currentCertStream != null) { m_currentCertStream.Close(); m_currentCertStream = null; }
			if (m_currentKeyPair != null) { m_currentKeyPair = null; }

			LoadDefaultSettings();
			ChangeSaveStatus(false);
		}

		#endregion

		#region ** LoadStoreDropdownLists **

		private void LoadStoreDropdownLists()
		{
			cboStoreLocation.Items.Clear();
			foreach (SSCX509.StoreLocation storeLocation in Enum.GetValues(typeof(SSCX509.StoreLocation)))
			{
				int index = cboStoreLocation.Items.Add(storeLocation);
				if (SSCX509.StoreLocation.LocalMachine == storeLocation)
					cboStoreLocation.SelectedIndex = index;
			}

			cboStoreName.Items.Clear();
			foreach (SSCX509.StoreName storeName in Enum.GetValues(typeof(SSCX509.StoreName)))
			{
				int index = cboStoreName.Items.Add(storeName);
				if (SSCX509.StoreName.My == storeName)
					cboStoreName.SelectedIndex = index;
			}
		}

		#endregion

		#region ** LoadDefaultSettings **

		private void LoadDefaultSettings()
		{
			DateTime today = DateTime.Today;

			//txtCommonName2.Text = null;
			cboSignatureAlgorithm.SelectedIndex = 0;
			cboKeySize.Text = "2048";
			dtpValidFrom.Value = today.AddDays(-7); // just to be safe
			dtpValidTo.Value = today.AddYears(10);
			ChangeSaveStatus(false);
		}

		#endregion

		#region ** ChangeSaveStatus **

		private void ChangeSaveStatus(Boolean canSave)
		{
			btnGenerate.Enabled = !canSave;
			btnExport.Enabled = canSave;
		}

		#endregion

		#region ** Event Handlers **

		#region * btnExport_Click *

		private void btnExport_Click(object sender, EventArgs e)
		{
			var fileName = txtFilename.Text.Trim();
			if (fileName.IsNullOrWhiteSpace())
			{
				MessageBox.Show("Please intput the export certificate filename", "Export", MessageBoxButtons.OK);
				return;
			}

			#region SelfSigned

			if (m_certType == GenerateCertificateType.SelfSigned)
			{
				SaveAsPFX();
				SaveAsCER();
				SaveCertInfo();
			}

			#endregion

			#region Root

			else if (m_certType == GenerateCertificateType.Root)
			{
				SaveAsPFX();
				SaveAsCER();
				SaveCertPublic();
				SaveCertPrivte();
				SaveCertInfo();
			}

			#endregion

			#region Intermediate

			else if (m_certType == GenerateCertificateType.Intermediate)
			{
				SaveAsPFX();
				SaveAsCER();
				SaveCertPublic();
				SaveCertPrivte();
				SaveCertInfo();
			}

			#endregion

			#region EndEntity

			else if (m_certType == GenerateCertificateType.EndEntity)
			{
				SaveAsPFX();
				SaveAsCER();
				SaveCertInfo();
			}

			#endregion
		}

		#endregion

		#region * btnSaveToCertStore_Click *

		private void btnSaveToCertStore_Click(object sender, EventArgs e)
		{
			var store = new SSCX509.X509Store((SSCX509.StoreName)cboStoreName.SelectedItem, (SSCX509.StoreLocation)cboStoreLocation.SelectedItem);
			store.Open(SSCX509.OpenFlags.ReadWrite);

			//var cert = GenerateCert();
			//if (null != cert)
			//{
			//	// I've not been able to figure out what property isn't getting copied into the store,
			//	// but IIS can't find the private key when I simply add the cert directly to the store
			//	// in this fashion:  store.Add(cert);
			//	// The extra two lines of code here does seem to make IIS happy though.
			//	// I got this idea from here: http://www.derkeiler.com/pdf/Newsgroups/microsoft.public.inetserver.iis.security/2008-03/msg00020.pdf
			//	//  (written by David Wang at blogs.msdn.com/David.Wang)
			//	byte[] pfx = cert.Export(SSCX509.X509ContentType.Pfx);
			//	cert = new SSCX509.X509Certificate2(pfx, (string)null, SSCX509.X509KeyStorageFlags.PersistKeySet | SSCX509.X509KeyStorageFlags.MachineKeySet);

			//	// NOTE: it's not clear to me at this point if this will work if you want to save to StoreLocation.CurrentUser
			//	//       given that there's also an X509KeyStorageFlags.UserKeySet. That could be DPAPI related though, and not cert store related.

			//	store.Add(cert);
			//}
			//store.Close();

			//if (null != cert)
			//{
			//	new CertDetailsForm
			//	{
			//		Certificate = cert,
			//		CertStoreLocation = (SSCX509.StoreLocation)cboStoreLocation.SelectedItem,
			//		CertStoreName = (SSCX509.StoreName)cboStoreName.SelectedItem,
			//	}.ShowDialog();
			//}
		}

		#endregion

		#region * btnReset_Click *

		private void btnReset_Click(object sender, EventArgs e)
		{
			Reset();
		}

		#endregion

		#region * btnGenerate_Click *

		private void btnGenerate_Click(object sender, EventArgs e)
		{
			CreateCertificate();
			ChangeSaveStatus(true);
		}

		#endregion

		#region * btnLoadIssuerCert_Click *

		private void btnLoadIssuerCert_Click(object sender, EventArgs e)
		{
			var frmCert = new FrmIssuerCert();
			frmCert.ShowDialog(this);
			if (frmCert.DialogResult == System.Windows.Forms.DialogResult.OK)
			{
				if (frmCert.IssuerCert != null)
				{
					m_issuerCert = frmCert.IssuerCert;
					if (m_issuerCert == null) { return; }
					m_issuerKeyPair = frmCert.IssuerKeyPair;
					if (m_issuerKeyPair == null) { return; }
					btnGenerate.Enabled = true;

					var subject = PrincipalUtilities.GetSubjectX509Principal(m_issuerCert);
					var oids = subject.GetOidList();
					var values = subject.GetValueList();
					var idx = 0;
					foreach (DerObjectIdentifier item in oids)
					{
						if (item.Id == X509Name.CN.Id)
						{
							txtCommonName1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.O.Id)
						{
							txtOrganization1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.OU.Id)
						{
							txtUnitName1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.E.Id)
						{
							txtEmail1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.TelephoneNumber.Id)
						{
							txtTelephone1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.Street.Id)
						{
							txtStreet1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.L.Id)
						{
							txtLocality1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.ST.Id)
						{
							txtProvince1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.C.Id)
						{
							txtCountry1.Text = values[idx] + "";
						}
						else if (item.Id == X509Name.PostalCode.Id)
						{
							txtPostalCode1.Text = values[idx] + "";
						}
						idx++;
					}
					//foreach (var item in values)
					//{
					//	CuteAnt.Log.HmTrace.WriteWarn(item.ToString() + " $$ " + item.GetType().FullName);
					//}
				}
			}
		}

		#endregion

		#region * cboCertType_SelectedIndexChanged *

		private void cboCertType_SelectedIndexChanged(object sender, EventArgs e)
		{
			Reset();

			m_certType = (GenerateCertificateType)cboCertType.SelectedIndex;
			if (m_certType == GenerateCertificateType.SelfSigned || m_certType == GenerateCertificateType.Root)
			{
				btnLoadIssuerCert.Enabled = false;
				grbIssuer.Enabled = true;
				btnGenerate.Enabled = true;
			}
			else
			{
				btnLoadIssuerCert.Enabled = true;
				grbIssuer.Enabled = false;
				btnGenerate.Enabled = false;
			}
			if (m_issuerCert != null) { m_issuerCert = null; }
			if (m_issuerKeyPair != null) { m_issuerKeyPair = null; }
		}

		#endregion

		private void cmdBrowse_Click(object sender, EventArgs e)
		{
			var folderDialog = new FolderBrowserDialog();

			if (DialogResult.OK == folderDialog.ShowDialog(this))
			{
				txtPath.Text = folderDialog.SelectedPath;
			}
		}

		#endregion
	}
}
